-- C3A0005.A
--
--                             Grant of Unlimited Rights
--
--     Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--     F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained 
--     unlimited rights in the software and documentation contained herein.
--     Unlimited rights are defined in DFAR 252.227-7013(a)(19).  By making 
--     this public release, the Government intends to confer upon all 
--     recipients unlimited rights  equal to those held by the Government.  
--     These rights include rights to use, duplicate, release or disclose the 
--     released technical data and computer software in whole or in part, in 
--     any manner and for any purpose whatsoever, and to have or permit others 
--     to do so.
--
--                                    DISCLAIMER
--
--     ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--     DISCLOSED ARE AS IS.  THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED 
--     WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--     SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE 
--     OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--     PARTICULAR PURPOSE OF SAID MATERIAL.
--*
--
-- OBJECTIVE: 
--      Check that access to subprogram may be stored within record 
--      objects, and that the access to subprogram can subsequently 
--      be called. 
-- 
-- TEST DESCRIPTION:
--      Declare an access to procedure type in a package specification.  
--      Declare two different procedures that can be referred to by the 
--      access to procedure type.  Declare a record with the access to 
--      procedure type as a component.  Use the access to procedure type to 
--      initialize the component of a record.  
--
--      In the main program, declare an operation.  An access value 
--      designating this operation is passed as a parameter to be 
--      stored in the record.
--
--
-- CHANGE HISTORY:
--      06 Dec 94   SAIC    ACVC 2.0
--
--!

package C3A0005_0 is

   Default_Call   : Boolean := False;

   type Button;


   -- Type accesses to procedures Push and Default_Response
   type Button_Response_Ptr is access procedure
      (B : access Button);

   procedure Push (B : access Button);

   procedure Set_Response (B : access Button;
                           R : in Button_Response_Ptr);

   procedure Default_Response  (B : access Button);

   Emergency_Call : Boolean := False;

   procedure Emergency (B : access C3A0005_0.Button);

   type Button is
      record
         Response :  Button_Response_Ptr
                  := Default_Response'Access;   
      end record;

end C3A0005_0;


-----------------------------------------------------------------------------

with TCTouch;
package body C3A0005_0 is

   procedure Push (B : access Button) is
   begin
      TCTouch.Touch( 'P' ); --------------------------------------------- P
      -- Invoking subprogram designated by access value
      B.Response (B);
   end Push;


   procedure Set_Response (B : access Button;
                           R : in     Button_Response_Ptr) is
   begin
      TCTouch.Touch( 'S' ); --------------------------------------------- S
      -- Set procedure value in record
      B.Response := R;
   end Set_Response;


   procedure Default_Response (B : access Button) is
   begin
      TCTouch.Touch( 'D' ); --------------------------------------------- D
      Default_Call := True;
   end Default_Response;


   procedure Emergency (B : access C3A0005_0.Button) is
   begin
      TCTouch.Touch( 'E' ); --------------------------------------------- E
      Emergency_Call := True;
   end Emergency;

end C3A0005_0;


-----------------------------------------------------------------------------

with TCTouch;
with Report;

with C3A0005_0;

procedure C3A0005 is

   Big_Red_Button : aliased C3A0005_0.Button;

begin

   Report.Test ("C3A0005", "Check that access to subprogram may be "
                         & "stored within data structures, and that the "
                         & "access to subprogram can subsequently be called");

   C3A0005_0.Push (Big_Red_Button'Access);
   TCTouch.Validate("PD", "Using default value");
   TCTouch.Assert( C3A0005_0.Default_Call, "Default Call" );

   -- set Emergency value in Button.Response
   C3A0005_0.Set_Response(Big_Red_Button'Access, C3A0005_0.Emergency'Access);

   C3A0005_0.Push (Big_Red_Button'Access);
   TCTouch.Validate("SPE", "After set to Emergency value");
   TCTouch.Assert( C3A0005_0.Emergency_Call, "Emergency Call");

   Report.Result;

end C3A0005;
